package cn.tedu.submarine;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

import javax.swing.*;
import javax.swing.plaf.synth.SynthOptionPaneUI;
import java.awt.Graphics;
import java.io.*;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

/*整个游戏世界*/
public class World extends JPanel {//2
    public static final int WIDTH = 641;//窗口宽
    public static final int HEIGHT = 479;//窗口高

    public static final int RUNNING = 0;//运行状态
    public static final int PAUSE   = 1;//暂停状态
    public static final int GAME_OVER= 2;//游戏结束状态
    private  int state = RUNNING;//当前状态(默认为运行状态

    //以下为窗口中显示的对象quzn
    private Battleship  ship       = new Battleship();
    private SeaObject[] submarines = {};
    private Mine[]      mines      = {};
    private Bomb[]      bombs      = {};

    /** 随机生成潜艇对象**/
    private SeaObject nextSubmarine() {
        Random rand = new Random();
        int type = rand.nextInt(3);
        if (type == 0) {
            return new ObserveSubmarine();
        } else if (type == 1) {
            return new TorpedoSubmarine();
        } else {
            return new MineSubmarine();
        }
    }

    private int subEnterIndex = 0;

    /**生成潜艇**/
    private void submarineEnterAction() {
        subEnterIndex++;
        if (subEnterIndex % 40 == 0) {
            SeaObject obj = nextSubmarine();
            submarines = Arrays.copyOf(submarines, submarines.length + 1);
            submarines[submarines.length - 1] = obj;
        }
    }

    private int mineEnterIndex = 0;

    /**水雷入场*/
    private void mineEnterAction() {
        mineEnterIndex++;
        if (mineEnterIndex % 40 == 0) {
            for (int i = 0;i < submarines.length;i++){
                if (submarines[i] instanceof MineSubmarine){//若潜艇是水雷潜艇
                    MineSubmarine ms = (MineSubmarine)submarines[i];//将潜艇强转为水雷潜艇
                    Mine obj = ms.shootMine();//获取水雷对象
                    mines =Arrays.copyOf(mines,mines.length+1);
                    mines[mines.length-1] = obj;

                }
            }
        }
    }

    /**海洋对象移动*/
    private void moveAction() {
        for (int i = 0; i < submarines.length; i++) {
            submarines[i].move();
        }
        for (int i = 0; i < mines.length; i++) {
            mines[i].move();
        }
        for (int i = 0; i < bombs.length; i++) {
            bombs[i].move();
        }
    }

    /**删除越界的海洋对象*/
    private void outOfBoundsAction() {
        for (int i = 0; i < submarines.length; i++) {
            /**越界的或者死了的**/
            if (submarines[i].isOutofBounds()||submarines[i].isDead()) {
                submarines[i] = submarines[submarines.length - 1];
                submarines    = Arrays.copyOf(submarines, submarines.length - 1);

            }
        }

        for (int i = 0; i < mines.length; i++) {
            if (mines[i].isOutofBounds()) {
                mines[i] = mines[mines.length - 1];
                mines    = Arrays.copyOf(mines, mines.length - 1);
            }
        }

        for (int i = 0; i < bombs.length; i++) {
            if (bombs[i].isOutofBounds()) {
                bombs[i] = bombs[bombs.length - 1];
                bombs    = Arrays.copyOf(bombs, bombs.length - 1);
            }
        }
    }

    private int score = 0;//玩家得分
    /**深水炸弹和潜艇碰撞**/
    private void bombBangAction(){
        for (int i = 0 ;i <bombs.length;i++){
            Bomb b = bombs[i];//获取每个炸弹
            for (int j = 0;j < submarines.length;j++){
                SeaObject s =submarines[j];//获取每个潜艇
                if(b.isLive() && s.isLive() && s.isHit(b)){//撞上了
                    s.goDead();
                    b.goDead();
                    if (s instanceof EnemyScore){//玩家若被撞得分
                        EnemyScore es = (EnemyScore)s;//将被撞对象强转为得分接口
                        score += es.getScore();//玩家得分
                    }
                    if(s instanceof EnemyLife){//若被撞对象为名
                        EnemyLife el = (EnemyLife) s;//讲被撞对象强转为得命接口
                        int num = el.getLife();//获取命数
                        ship.addLife(num);//战绩增命
                    }

                }
            }
        }
    }

    private void mineBangAction(){
        for (int i = 0;i <mines.length;i++){//遍历所有水雷
            Mine m = mines[i];//获取水雷
            if(m.isLive() && ship.isLive() && m.isHit(ship)){//若都或者，并且碰撞了
                m.goDead();//水雷死
                ship.subtractLife();//战舰减命
            }
        }
    }

    private void cheGameOverAction(){
        if(ship.getLife() <= 0){//若战舰命数《=0，表示游戏结束
            state = GAME_OVER;//将当前状态改为GAME_OVER游戏结束状态

        }
    }
    /**读取游戏存档**/
    private void loadGame(){
        //判读是否有存档文件
        File file = new File("save.sav");
        if (file.exists()){
            int r = JOptionPane.showConfirmDialog(this,"是否读档");
            if (r== JOptionPane.YES_NO_OPTION){//如果按的确定按钮
                //加载存档
                try {
                    FileInputStream fis   = new FileInputStream(file);
                    ObjectInputStream ois = new ObjectInputStream(fis);
                    SaveInfo saveInfo     = (SaveInfo)ois.readObject();
                    ois.close();

                    ship           = saveInfo.getShip();
                    submarines     = saveInfo.getSubmarines();
                    mines          = saveInfo.getMines();
                    bombs          = saveInfo.getBombs();
                    subEnterIndex  = saveInfo.getSubEnterIndex();
                    mineEnterIndex = saveInfo.getMineEnterIndex();
                    score          = saveInfo.getScore();

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    }

    /****启动程序的执行*/
    public void action() {
        loadGame();//读取游戏存档
        KeyAdapter k = new KeyAdapter() {
            /**按键弹起事件*/
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_P){
                    state=PAUSE;//将游戏暂停
                    //返回值表达用户按了哪个按钮
                    int r =JOptionPane.showConfirmDialog(World.this,"确定保存游戏？");
                    //如果用户按了确定啧保存进度
                    if (r == JOptionPane.YES_NO_OPTION){
                        SaveInfo saveInfo = new SaveInfo(
                                ship,submarines, mines,bombs,score,
                                mineEnterIndex,subEnterIndex);

                        try {
                            FileOutputStream fos = new FileOutputStream("save.sav");
                            ObjectOutputStream oos = new ObjectOutputStream(fos);
                            oos.writeObject(saveInfo);
                            oos.close();
                        } catch (IOException ioException) {
                            ioException.printStackTrace();
                        }
                        System.out.println("开始保存游戏~~~~~~~~");
                    }
                    state =RUNNING;//操作后将游戏恢复
                    /*if (state ==RUNNING){
                        state = PAUSE;
                    }else if(state == PAUSE){
                        state = RUNNING;
                    }*/
                }
                    if (state != RUNNING){
                     return;
                }
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                    Bomb obj = ship.shootBomb();
                    Bomb obj1 = ship.shootBomb2();
                    Bomb obj2 = ship.shootBomb3();

                    bombs = Arrays.copyOf(bombs, bombs.length + 3);
                    bombs[bombs.length - 1] = obj;
                    bombs[bombs.length - 2] = obj1;
                    bombs[bombs.length - 3] = obj2;
                    //为什么这里没有repaint()也能按一下空格就发射
                }
                if (!ship.isOutofBounds()){
                    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                        ship.moveLeft();
                    }
                    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                        ship.moveRight();
                    }
                    if (e.getKeyCode() == KeyEvent.VK_UP) {
                        ship.moveUp();
                    }
                    if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                        ship.moveDown();
                    }
                }else if(ship.isLeftOutofBound()){
                    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                        ship.moveRight();
                    }
                }else if (ship.isRightOutofBound()){
                    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                        ship.moveLeft();
                    }
                }
            }
        };//键盘侦听器
        this.addKeyListener(k);//添加侦听

        Timer timer = new Timer();//定时器对象
        int interval = 10;//定时间隔（以毫秒为单位）
        timer.schedule(new TimerTask() {
            public void run() {//定时干的事儿
                if (state == RUNNING) {//仅在运行状态执行
                    submarineEnterAction();//三种潜艇
                    mineEnterAction();//水雷入场
                    moveAction();//海洋对象移动
                    outOfBoundsAction();//删除越界的海洋对象
                    System.out.println(submarines.length+","+mines.length+","+bombs.length);
                    bombBangAction();
                    mineBangAction();//水雷与战舰的碰撞
                    cheGameOverAction();//检测游戏结束
                    repaint();//重新调用paint()方法-----不需要掌握

                }
            }
        }, interval, interval);
    }

    /***往窗口中画东西*/
    public void paint(Graphics g) {//由系统自动调用
        Images.sea.paintIcon(null, g, 0, 0);
        ship.paintImage(g);
        for (int i = 0; i < submarines.length; i++) {
            submarines[i].paintImage(g);
        }
        for (int i = 0; i < mines.length; i++) {
            mines[i].paintImage(g);
        }
        for (int i = 0; i < bombs.length; i++) {
            bombs[i].paintImage(g);
        }
        g.drawString("SCORE:"+score,200,50);
        g.drawString("LIFE:"+ship.getLife(),400, 50);

        if (state == GAME_OVER){//若当前状态是游戏结束状态
            Images.gameover.paintIcon(null, g, 0, 0);
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();//3
        World world = new World();//加载World构造方法
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH + 16, HEIGHT + 39);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);//自动调用paint

        world.action();//启动程序的执行
    }

}


/*

 */

